package package1;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class AutoUnpackEverydayOld {
	public static String DESKTOP = "c:\\users\\alvin.wang\\desktop";
	public static String WORKSPACE = "D:\\Program Files\\workspace";
	public static String JARLOCATION = "D:\\Program Files\\eclipse\\jar scripts";
	public static String PROJECTNAME = "JavaLearning";
	public static String PACKAGENAME = "package1";
	public static String className = getClassName();
	public static String ZIPLOG = "";
	public static String HOME = "HOME";
	public static String OFFICE = "OFFICE";
	public static String PLACE = OFFICE;
	public static boolean testBat = false;
	public static boolean showDebugLog = true;
	public static String archiveFolderName = "JAVA ARCHIVE";

	public static void main(String[] args) throws Exception {
		initializingParameters();
		createJarFileInLocationFolder();
		// runJavaFileForAutoUnpackEveryday();
	}

	@SuppressWarnings("unused")
	private static void runJavaFileForAutoUnpackEveryday() throws Exception {

		// start from cmd on desktop, current folder is desktop
		String cmd = "jar xf " + DESKTOP + "\\" + "AutoPackEveryday.zip";
		run(cmd);

		// copy unziped files to workspace
		File[] files = new File(archiveFolderName).listFiles();
		String copyToAddr = ZIPLOG + "\\" + PACKAGENAME;
		copyToFolder(files, copyToAddr);
		log(copyToAddr);

		// delete unziped files and folders
		String javaFolder = DESKTOP + "\\" + archiveFolderName;
		String metaFolder = DESKTOP + "\\" + "meta-inf";
		deleteFolder(javaFolder);
		deleteFolder(metaFolder);
	}

	private static void log(String... arr) throws IOException {
		BufferedWriter bw = new BufferedWriter(new FileWriter("log.txt"));
		for (String a : arr)
			bw.write(a + "\r\n");
		bw.close();
	}

	private static void copyToFolder(File[] files, String folder) throws Exception {
		folderCheck(new File(folder));
		copyToFolder(files, new File(folder));// files to folder
	}

	private static void copyToFolder(File[] files, File folder) throws Exception {
		folderCheck(folder);
		for (File f : files) {
			if (f.isDirectory())
				copyToFolder(f, folder);// folder to folder
			else
				copyToFile(f, folder + "\\" + f.getName());// file to folder
		}
	}

	private static void copyToFolder(File folder1, File folder2) throws Exception {
		folderCheck(folder2);
		// create f1 folder in f2
		File f = new File(folder2, folder1.getName());
		if (!f.exists())
			f.mkdirs();
		// copy f1 contents File[] to f2
		copyToFolder(folder1.listFiles(), folder2);// files to folder
	}

	private static void folderCheck(File file) throws Exception {
		if (!file.isDirectory())
			throw new Exception(file.getName() + " is not a directory");
	}

	private static void copyToFile(File f1, String f2Addr) throws Exception {
		File f2 = new File(f2Addr);
		if (f2.isDirectory())
			copyToFolder(f1, f2);
		else
			copyToFile(f1, f2);
	}

	@SuppressWarnings("unused")
	private static void copyToFile(String f1, String f2) throws Exception {
		copyToFile(new File(f1), new File(f2));
	}

	private static void copyToFile(File f1, File f2) throws Exception {
		boolean deleted = true;
		if (f2.exists()) {
			deleted = f2.delete();
			if (!deleted)
				throw new Exception("File " + f2.getName() + " is in use, thus cannot be deleted!");
		}
		boolean needDealingWithLine = false;
		if (needDealingWithLine) {
			BufferedReader br = new BufferedReader(new FileReader(f1));
			BufferedWriter bw = new BufferedWriter(new FileWriter(f2));
			String buf;
			while ((buf = br.readLine()) != null)
				bw.write(buf + "\r\n");
			br.close();
			bw.close();
		} else {
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1));
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2));
			byte[] b = new byte[1024];
			int pos;
			while ((pos = bis.read(b)) != -1) {
				bos.write(b, 0, pos);
				bos.flush();
			}
			bis.close();
			bos.close();
		}
	}

	private static void createJarFileInLocationFolder() throws IOException {
		// copy Java File and do some hack
		File javaFile = new File(className + ".java");
		String javaFilePath = getCurrentJavaFilePath();
		BufferedReader br = new BufferedReader(new FileReader(new File(javaFilePath)));
		BufferedWriter bw = new BufferedWriter(new FileWriter(javaFile));
		String buf;
		while ((buf = br.readLine()) != null) {
			if (buf.contains("package " + PACKAGENAME + ";") && !buf.contains("if"))
				buf = "";
			if (buf.contains("createJarFileInLocationFolder();") && !buf.contains("if"))
				buf = "//" + buf;
			if (buf.contains("runJavaFileForAutoUnpackEveryday();") && !buf.contains("if"))
				buf = removeMark(buf);
			bw.write(buf);
			bw.newLine();
		}
		bw.close();
		br.close();

		// compileJavaClass
		String cmd = "javac " + quoteAddress(javaFile.getAbsolutePath());
		run(cmd);

		// create mf file
		File mf = new File("manifest.mf");
		bw = new BufferedWriter(new FileWriter(mf));
		bw.write("Main-Class: " + className + "\r\n");
		bw.close();

		// pack into jar file and place in the scripts location
		File classFile = new File(className + ".class");
		cmd = "jar vcfm " + quoteAddress(JARLOCATION + "\\" + className + ".jar") + " "
				+ quoteAddress(mf.getAbsolutePath()) + " " + classFile.getPath() + " " + javaFile.getName();
		run(cmd);

		// delete java, class and mf file
		javaFile.delete();
		classFile.delete();
		mf.delete();

		// create auto pack bat file
		File batFile = new File(DESKTOP + "\\" + className + ".bat");
		bw = new BufferedWriter(new FileWriter(batFile));
		cmd = "java -jar " + quoteAddress(JARLOCATION + "\\" + className + ".jar");
		bw.write(cmd);
		bw.close();

		// test
		if (testBat)
			run(batFile.getAbsolutePath());
		System.err.println("End of the program.");
	}

	private static void initializingParameters() throws Exception {
		// initial parameters
		String user = System.getenv().get("USERNAME");
		if (user.equalsIgnoreCase("alvin.wang"))
			PLACE = OFFICE;
		else if (user.equalsIgnoreCase("alvin"))
			PLACE = HOME;
		else
			throw new Exception("Place invalid, neither @home nor @office, please check!");
		System.err.println("This is @ " + PLACE);
		if (PLACE == HOME) {
			DESKTOP = "C:\\Users\\Alvin\\Desktop";
			WORKSPACE = "D:\\Program Files\\Java\\WorkSpace";
			JARLOCATION = "D:\\Program Files\\Java\\jar scripts";
		} else if (PLACE == OFFICE) {
			DESKTOP = "c:\\users\\alvin.wang\\desktop";
			WORKSPACE = "D:\\Program Files\\workspace";
			JARLOCATION = "D:\\Program Files\\eclipse\\jar scripts";
		}
		ZIPLOG = WORKSPACE + "\\" + PROJECTNAME + "\\src";
	}

	private static String getClassName() {
		String a = Thread.currentThread().getStackTrace()[1].getClassName();
		int b = a.indexOf(".");
		String c = a.substring(b + 1, a.length());
		return c;
	}

	private static void run(String string) throws IOException {
		Process p = Runtime.getRuntime().exec(string);
		InputStream is1 = p.getInputStream();
		InputStream is2 = p.getErrorStream();
		BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
		BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
		String b1, b2;
		StringBuffer sb1 = new StringBuffer();
		StringBuffer sb2 = new StringBuffer();
		while ((b1 = br1.readLine()) != null)
			sb1.append(b1 + "\r\n");
		while ((b2 = br2.readLine()) != null)
			sb2.append(b2 + "\r\n");
		br1.close();
		br2.close();
		b1 = ("Process inputStream message:\r\n" + sb1.toString()).trim();
		b2 = ("Process errorStream message:\r\n" + sb2.toString()).trim();
		if (!sb1.toString().equals("") && showDebugLog) {
			System.err.println("Process inputStream message:\r\n" + sb1.toString().trim());
			writeToFile(DESKTOP + "\\InputStream.txt", b1);
		}
		if (!sb2.toString().equals("") && showDebugLog) {
			System.err.println("Process errorStream message:\r\n" + sb2.toString().trim());
			writeToFile(DESKTOP + "\\ErrorStream.txt", b2);
		}
	}

	private static void writeToFile(String fileName, String str) throws IOException {
		File f = new File(DESKTOP + "\\" + new File(fileName).getName());
		BufferedWriter bw = new BufferedWriter(new FileWriter(f));
		bw.write(str);
		bw.close();
	}

	public static void openCurrentFolder() throws IOException {
		open(getCurrentFolder());
	}

	private static String getCurrentFolder() {
		return System.getProperty("user.dir");
	}

	public static void open(String string) throws IOException {
		java.awt.Desktop.getDesktop().open(new File(string));
	}

	/**
	 * add '"' surround the path so CMD could recognize
	 * 
	 * @param string
	 * @return
	 */
	private static String quoteAddress(String string) {
		return "\"" + string + "\"";
	}

	private static String getCurrentJavaFilePath() throws IOException {
		String a = System.getProperty("user.dir");
		// D:\Program Files\Java\WorkSpace\JavaLearning
		String b = Thread.currentThread().getStackTrace()[1].getClassName();
		// package1.AutoPackEveryday
		b = b.replace(".", "\\");
		return a + "\\src" + "\\" + b + ".java";
	}

	/**
	 * remove the mark for some code //public void to make it available
	 * 
	 * @param buf
	 * @return
	 */
	private static String removeMark(String buf) {
		String mark = "//";
		int b = buf.indexOf(mark);
		String c = buf.substring(b + mark.length(), buf.length()).trim();
		return "\t\t" + c;
	}

	private static void deleteFolder(String name) {
		File folder = new File(name);
		for (File f : folder.listFiles())
			if (f.isFile())
				f.delete();
			else
				deleteFolder(f.getAbsolutePath());
		folder.delete();
	}
}
